import hashlib, shutil
import json
import os, rumps


class GitFlowBarApp(rumps.App):
    def __init__(self, tomCatContext):
        self.TomCatContext = tomCatContext
        self.md5Map = {}
        super(GitFlowBarApp, self).__init__("Git Flow", icon='user-secret.png', title='')
        self.menu = self.build()

    @rumps.timer(2)
    def refresh(self, _=None):
        # 前置处理
        self.md5Map.clear()
        if 'Quit' in self.menu.keys():
            self.menu.pop(key='Quit')
        # 重构处理
        msg = ''
        for name, model in TomCatContext.items():
            elements = model.configElements()
            if len(elements) > 0:
                file_path = []
                file_info = {}
                for ele in elements:
                    mark_name = ele['name']
                    file_path.append(mark_name)
                    file_info[mark_name] = ele
                    self.menu[name][mark_name] = rumps.MenuItem('🫙' + mark_name, callback=self.config, template=name)
                self.md5Map[name] = file_info
                # 更新菜单信息
                item_name = self.menu[name].keys()
                ret_diff = list(set(file_path) ^ set(item_name))
                for diff in ret_diff:
                    self.menu[name].pop(key=diff)
                # 设置启动状态
                md5_info = model.tomCatMd5()
                flags = True
                for k, i in self.md5Map[name].items():
                    if i['xml'] == md5_info['xml'] and i['war'] == md5_info['war']:
                        flags = False
                        if len(self.TomCatContext) == 1:
                            self.title = i['name']
                        else:
                            self.title = 'TomFlow'
                        for key, value in self.menu[name].items():
                            value.title = value.title.replace('🍺', '🫙')
                        self.menu[name][k].title = self.menu[name][k].title.replace('🫙', '🍺')
                if flags:
                    msg += name + ','
        if msg != '':
            markStr = msg + 'mark'
            self.title = markStr.replace(',mark', '[未知配置]')

    def build(self):
        menus = []
        for name, model in TomCatContext.items():
            elements = model.configElements()
            if len(elements) > 0:
                menu = rumps.MenuItem(name, key=name)
                for file_name in elements:
                    mark_name = file_name['name']
                    menu[mark_name] = rumps.MenuItem('🫙' + mark_name, callback=self.config, template=name)
                menus.append(menu)
        return menus

    def config(self, _):
        for key, value in self.menu[_.template].items():
            value.title = value.title.replace('🍺', '🫙')
        if len(self.TomCatContext) == 1:
            self.title = _.title.replace('🫙', '').replace('🍺', '')
        else:
            _.title = _.title.replace('🫙', '🍺')
        self.TomCatContext[_.template].doFileReload(self.md5Map[_.template][_.title.replace('🍺', '')])

    @rumps.clicked("退出应用")
    def takeout(self, _):
        rumps.quit_application()


def fileMd5(filePath):
    with open(filePath, 'rb') as f:
        return hashlib.sha256(f.read()).hexdigest()


class TomCatModel:
    def __init__(self, strDict, gitPath):
        self.name = strDict['name']
        self.path = strDict['path']
        self.git = gitPath

    def configElements(self):
        elements = []
        for file_name in os.listdir(self.git):
            current_file = self.git + '/' + file_name
            if os.path.isfile(current_file) or file_name == '.DS_Store':
                continue
            else:
                if {'SuperModel.war', 'context.xml'}.issubset(os.listdir(current_file)):
                    elements.append({
                        'name': file_name,
                        'war': fileMd5(current_file + '/SuperModel.war'),
                        'xml': fileMd5(current_file + '/context.xml'),
                    })
        return elements

    def tomCatMd5(self):
        md5_info = {'war': '', 'xml': ''}
        if os.path.exists(self.path + '/webapps/SuperModel.war') and os.path.exists(self.path + '/conf/context.xml'):
            md5_info['war'] = fileMd5(self.path + '/webapps/SuperModel.war')
            md5_info['xml'] = fileMd5(self.path + '/conf/context.xml')
        return md5_info

    def doFileReload(self, info):
        my_info = self.tomCatMd5()
        if my_info['xml'] != info['xml']:
            if os.path.exists(self.path + '/conf/context.xml'):
                os.unlink(self.path + '/conf/context.xml')
            if os.path.exists(self.git + '/' + info['name'] + "/context.xml"):
                shutil.copy(src=self.git + '/' + info['name'] + "/context.xml", dst=self.path + '/conf/')
        if my_info['war'] != info['war']:
            if os.path.exists(self.path + '/webapps/SuperModel.war'):
                os.unlink(self.path + '/webapps/SuperModel.war')
            if os.path.exists(self.path + '/webapps/SuperModel'):
                shutil.rmtree(self.path + '/webapps/SuperModel')
            if os.path.exists(self.git + '/' + info['name'] + "/SuperModel.war"):
                shutil.copy(src=self.git + '/' + info['name'] + "/SuperModel.war", dst=self.path + '/webapps/')


if __name__ == '__main__':
    # 打的包不包含sdk,以后还需要相应环境才能运行
    # python3 setup.py py2app -A
    # 打的包包含sdk,以后不需要相应环境就能运行
    # python3 setup.py py2app
    user_config = os.path.expanduser('~') + '/Documents/TomFlow.json'
    if os.path.exists(user_config):
        TomCatContext = {}
        with open(user_config, 'r', encoding='utf-8') as fcc_file:
            f = fcc_file.read()
            if f == '':
                os.unlink(user_config)
                pass
            fcc_data = json.loads(f)
            git = fcc_data['git_path']
            for inst in fcc_data['local_tomcat']:
                tomCatModel = TomCatModel(inst, git)
                TomCatContext[tomCatModel.name] = tomCatModel
        GitFlowBarApp(TomCatContext).run()
    else:
        # 配置不存在 需要写入模版
        config_file = open(user_config, 'w')
        config_file.write('''{\n    "local_tomcat": [\n        {\n        "name": "TomCat名称",            
        "path": "TomCat路径"\n        }\n    ],\n    "git_path": "IsolatedConfig项目路径"\n}''')
        config_file.close()

# {
#     "local_tomcat": [
#         {
#             "name": "TomCat名称",
#             "path": "/Users/anorak/Documents/apache-tomcat-8.5.88"
#         }
#     ],
#     "git_path": "/Users/anorak/Documents/JavaPro/EpmVenus/isolatedconfig/src/main/java/venus/sm/isolatedconfig"
# }
